# -*- coding: utf-8 -*-
"""
Created on Fri Aug 11 11:18:40 2023

@author: 李小斌
"""
import os
import math
import numpy as np
from sklearn.model_selection import KFold
#from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Ridge
from sklearn.linear_model import Lasso
from sklearn.ensemble import BaggingRegressor
from sklearn.tree import ExtraTreeRegressor
from sklearn import neighbors
from sklearn import svm
from sklearn import tree
from sklearn import ensemble
from sklearn.metrics import mean_squared_error
import csv
#from gplearn import genetic
#from gplearn.genetic import SymbolicRegressor
#from datetime import datetime

dimension=400
    
def ontime(modelname,nfolds,datasetn):
    csv_reader=csv.reader(open('all'+str(dimension)+'.csv'))
    
    L1=[]
    y=[]                        #期末成绩,final
    #x=[]                       #平时所有数据
    xtest=[]                      #平时测验
    xhomework=[]                  #平时2次作业
    xexperiment=[]              #平时的16次实验
    xevaluation=[]              #教学评价
    
    n=0
    for row in csv_reader:
        if n==0:
            n=n+1
            continue
        n=n+1
        y.append(row[1])                 #final
        xtest.append(row[2:4])           #2次平时测验
        xhomework.append(row[4:6])      #2次作业
        xexperiment.append(row[6:22])   #16次实验
        xevaluation.append(row[22:22+3*dimension])  #3次评价的语义嵌入
        

    
    #将所有数据转化为float类型数据
    ya=np.array(y,dtype=float)
    ya=ya/100
    xtesta=np.array(xtest,dtype=float)
    xtesta=xtesta/100    
    xhomeworka=np.array(xhomework,dtype=float) 
    xhomeworka=xhomeworka/100
    xexperimenta=np.array(xexperiment,dtype=float) 
    xexperimenta=xexperimenta/100
    xevaluationa=np.array(xevaluation,dtype=float)         
      

    """
    datasetn表示参与训练预测的X集合
    
    one->1:test 2:homework 3:experiment 4:evaluation 
    
    two->5:test+homwork 6:test+experiment 7:test+evaluation 8:homework+experiment
    9:homework+evaluation 10:experiment+evaluation
    
    three->11:test+homework+experiment 12:test+homework+evaluation 
    13:test+experiemnt+evaluation 14:homework+experiment+evaluation
    
    for->15:test+homework+experiment+evaluation    
    """
    xa=np.array([])
    if datasetn==1:
        xa=xtesta
    elif datasetn==2:
        xa=xhomeworka
    elif datasetn==3:
        xa=xexperimenta
    elif datasetn==4:
        xa=xevaluationa
    elif datasetn==5:
        xa=np.hstack((xtesta,xhomeworka))
    elif datasetn==6:
        xa=np.hstack((xtesta,xexperimenta))
    elif datasetn==7:
        xa=np.hstack((xtesta,xevaluationa))
    elif datasetn==8:
        xa=np.hstack((xhomeworka,xexperimenta))
    elif datasetn==9:  
        xa=np.hstack((xhomeworka,xevaluationa))
    elif datasetn==10:
        xa=np.hstack((xexperimenta,xevaluationa))
    elif datasetn==11:
        xa=np.hstack((xtesta,xhomeworka,xexperimenta))
    elif datasetn==12:
        xa=np.hstack((xtesta+xhomeworka,xevaluationa))
    elif datasetn==13:  
        xa=np.hstack((xtesta,xexperimenta,xevaluationa))
    elif datasetn==14:
        xa=np.hstack((xhomeworka,xexperimenta,xevaluationa))
    elif datasetn==15:    
        xa=np.hstack((xtesta,xhomeworka,xexperimenta,xevaluationa))
    """
    #数据预处理
    ya=ya/100
    for i in range(xexperimenta.shape[0]):
        for j in range(xexperimenta.shape[1]):
            if xexperimenta[i][j]==100:
                xexperimenta[i][j]=1
            else:
                xexperimenta[i][j]=0
   """             
    #nfolds=5
    kf = KFold(n_splits=nfolds,shuffle=False)  # 初始化KFold
    if modelname=='LR':
        model = LinearRegression()
    elif modelname=='Ridge':
        model = Ridge(alpha=.5)
    elif modelname=='Lasso':
        model=Lasso(alpha=.5)
    elif modelname=='SVR':
        model=svm.SVR()
    elif modelname=='DT':
        model=tree.DecisionTreeRegressor()
    elif modelname=='KNN':
        model=neighbors.KNeighborsRegressor()
    elif modelname=='RandomForest':
        model=ensemble.RandomForestRegressor(n_estimators=20)
    elif modelname=='Adaboost':
        model=ensemble.AdaBoostRegressor(n_estimators=20)
    elif modelname=='GBRT':
        model=ensemble.GradientBoostingRegressor(n_estimators=20)
    elif modelname=='Bagging':
        model=BaggingRegressor()
    elif modelname=='ExtraTree':
        model=ExtraTreeRegressor()
    #model用于预测测验，model1用于预测作业,model2用于预测实验，model3用于预测评价
    #model4用于合并预测

    for train_index , test_index in kf.split(ya):  # 调用split方法切分数据        
        #rmse0:只有测试
        model.fit(xa[train_index],ya[train_index])
        ypt0=model.predict(xa[test_index])
        rmse=math.sqrt(mean_squared_error(ya[test_index],ypt0))    
        
        L1.append(rmse)  #准备保存哪一种结果，最后对应哪一种的数据  
    return [L1]

def evaluate(modelname,ntimes,nfolds,datasetn):
    file=open(modelname+'.csv','w',newline='')       
    f_csv=csv.writer(file)
    header=['rmse']
    f_csv.writerow(header)
    times=0
    while times<ntimes:
        L=ontime(modelname,nfolds,datasetn)
        Lw=[]           #用于获取L1-L8中相同位置的rmse，构造成一个list存入csv    
        for pos in range(0,nfolds):
            for Litem in L:
                Lw.append(Litem[pos])
            f_csv.writerow(Lw)
            Lw=[]
        times+=1
    file.close()

def getRmse(modelname):
    filepath=modelname+'.csv'
    file=open(filepath)
    csv_reader=csv.reader(file)    
    x=[]
    n=0
    for row in csv_reader:
        if n==0:
            n=n+1
            continue
        n=n+1
        x.append(row[0])                    
    #将所有数据转化为float类型数据
    file.close()
    os.remove(filepath)
    xa=np.array(x,dtype=float)
    return np.mean(xa)

def getCompare():
      #模型名称，LR,Ridge,Lasso,SVR,DT,KNN,RandomForest,Adaboost,GBRT,Bagging,ExtraTree
    ntimes=20#运行总次数
    nfolds=5#fold的次数
    modelnames=['LR','Ridge','Lasso','SVR','DT','KNN','RandomForest',
                'Adaboost','GBRT','Bagging','ExtraTree']
    """
    datasetn表示参与训练预测的X集合
    
    one->1:test 2:homework 3:experiment 4:evaluation 
    
    two->5:test+homwork 6:test+experiment 7:test+evaluation 8:homework+experiment
    9:homework+evaluation 10:experiment+evaluation
    
    three->11:test+homework+experiment 12:test+homework+evaluation 
    13:test+experiemnt+evaluation 14:homework+experiment+evaluation
    
    for->15:test+homework+experiment+evaluation    
    """
    DatasetN=4
    Rtotal=[]
    Rtmp=[]
    for datasetn in range(1,DatasetN+1):
        for modelname in modelnames:
            evaluate(modelname,ntimes,nfolds,datasetn)
            v=getRmse(modelname)
            Rtmp.append(v)
        Rtotal.append(Rtmp)
        Rtmp=[]
    Rtotala=np.array(Rtotal)
    Rtotala=np.transpose(Rtotala)
    Rtotal=Rtotala.tolist()
    file=open('regression_compare'+str(dimension)+'.csv','w',newline='')  
    f_csv=csv.writer(file)
    header=['method']
    for col in range(1,DatasetN+1):
        header.append(col)
    f_csv.writerow(header)
    i=0
    for modelname in modelnames:
        temp=[modelname]
        for col in range(0,DatasetN):
            temp.append(Rtotal[i][col])
        f_csv.writerow(temp)
        i=i+1
    file.close() 


if __name__=="__main__":
    dimension=450
    getCompare()
"""    
    dimension=10
    getCompare()
    dimension=50
    getCompare()
    dimension=100
    getCompare()
    dimension=200
    getCompare()
    dimension=300
    getCompare()
    dimension=400
    getCompare()
    dimension=500
    getCompare()
    """